#define VERBOSE
#define DEBUG

using KMod;
using HarmonyLib;
using UnityEngine;
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using Database;
using Klei.AI;


namespace ONIMod
{
    public class MyUserMod : UserMod2 {
        public override void OnLoad(Harmony harmony)
        {
            Harmony.DEBUG = true;
            base.OnLoad(harmony);
            Debug.Log("Neutron3529's simple ONI mod is loaded.");
        }
        [HarmonyDebug]

        /*
        [HarmonyPatch(typeof(BaseMinionConfig), "AddMinionTraits")]
        class BaseMinionConfigAddMinionTraits{
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions){//机械臂拾取范围扩大
                Debug.Log("Neutron3529:开始注入MinionConfig的AddMinionTraits");
                uint flag=0xDEADBEFF;
                MethodInfo ModifierSetCreateTrait = typeof(ModifierSet).GetMethod("CreateTrait");
                foreach (var instruction in instructions) {
                    yield return instruction;// name=((FieldInfo)instruction.operand).Name;
                    if(flag==0xDEADBEFF && instruction.opcode==OpCodes.Callvirt && (MethodInfo)instruction.operand == ModifierSetCreateTrait){
                        Debug.Log("       [II]:开始复制人trait的函数注入.");
                        flag=0;
                        //yield return new CodeInstruction(OpCodes.Dup,null); // trait
                        yield return new CodeInstruction(OpCodes.Ldarg_1,null);// modifiers
                        yield return new CodeInstruction(OpCodes.Call,typeof(BaseMinionConfigAddMinionTraits).GetMethod("insert"));// call insert(trait,modifiers), return trait thus no more op is required.
                    }
                }
            }
            public static Trait insert(Trait trait,Modifiers modifiers){//机械臂拾取范围扩大
                string name="Mod";

                trait.Add(new AttributeModifier(Db.Get().Attributes.SpaceNavigation.Id,100f,name, false, false, true));

                // 下面是没有放在 modifiers.initialAttributes 的变量，不处理initialAttributes的话，读档会消失。

                modifiers.initialAttributes.Add(Db.Get().Attributes.Construction.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Construction.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Digging.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Digging.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Machinery.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Machinery.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Athletics.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Athletics.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Learning.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Learning.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Cooking.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Cooking.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Caring.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Caring.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Strength.Id);
                trait.Add(new AttributeModifier(Db.Get().Attributes.Strength.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Art.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.Art.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Botanist.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.Botanist.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Ranching.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.Ranching.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.LifeSupport.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.LifeSupport.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.Toggle.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.Toggle.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.PowerTinker.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.PowerTinker.Id,100f,name, false, false, true));
                modifiers.initialAttributes.Add(Db.Get().Attributes.FarmTinker.Id);
                  trait.Add(new AttributeModifier(Db.Get().Attributes.FarmTinker.Id,100f,name, false, false, true));

                trait.OnAddTrait = delegate(GameObject go) {
                    MinionResume component = go.GetComponent<MinionResume>();
                    if (component != null) {
                        Dictionary<string, bool> ownedHats = Traverse.Create(component).Field("ownedHats").GetValue<Dictionary<string, bool>>();
                        for(int i=0;i<Db.Get().Skills.Count;i++){
                            if (i > 6)
                            {
                                continue;
                            }
                            string skillId = Db.Get().Skills[i].Id;
                            component.MasteryBySkillID[skillId] = true;
                            //component.GrantSkill(skillId);
                            component.GrantedSkillIDs.Add(skillId);
                            if (!ownedHats.ContainsKey(Db.Get().Skills.Get(skillId).hat)) {
                                ownedHats.Add(Db.Get().Skills.Get(skillId).hat, false);
                            }
                        }
                    }
                };
                
                return trait;
            }
        }
        */

        [HarmonyPatch(typeof(BaseMinionConfig), "BaseMinion")]
        public class BaseMinionConfigAddMinionTraits
        {
          private static void Postfix(GameObject __result)
          {
            Debug.Log("开始 BaseMinion.");

            MinionModifiers modifiers = __result.AddOrGet<MinionModifiers>();
            string desc = "stronger pp";
            //Trait trait = Db.Get().traits.Get(modifiers.initialTraits[0]);
            string newTraitID = "strongerppTraitID";
            Trait newTrait = Db.Get().CreateTrait(newTraitID, desc, desc, (string) null, false, (ChoreGroup[]) null, true, true);

            modifiers.initialAttributes.Add(Db.Get().Attributes.Construction.Id);
            newTrait.Add(new AttributeModifier(Db.Get().Attributes.Construction.Id, 100f, desc));
            modifiers.initialAttributes.Add(Db.Get().Attributes.Digging.Id);
            newTrait.Add(new AttributeModifier(Db.Get().Attributes.Digging.Id, 100f, desc));
            modifiers.initialAttributes.Add(Db.Get().Attributes.Machinery.Id);
            newTrait.Add(new AttributeModifier(Db.Get().Attributes.Machinery.Id,100f, desc));

            modifiers.initialTraits.Add(newTraitID);
            Debug.Log("结束 AddMinionTraits.");
          }
        }
        [HarmonyPatch(typeof(HeadquartersConfig), "ConfigureBuildingTemplate")]
        public class SkillPointPatch
        {
            public static void Postfix(GameObject go)
            {
                go.AddOrGet<Telepad>().startingSkillPoints = 10f;
            }
        }
    }
}

